package com.haisen.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.haisen.core.utils.PageResultSet;
import com.haisen.dataobject.dto.JobNoDTO;
import com.haisen.dataobject.dto.TreeDto;
import com.haisen.dataobject.entity.JobNo;
import com.haisen.dataobject.mapper.base.JobNoMapper;
import com.haisen.dataobject.query.JobNoQuery;
import com.haisen.service.JobNoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import sun.security.util.Length;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class JobNoServiceImpl implements JobNoService {


    @Autowired
    private JobNoMapper jobNoMapper;

    @Override
    public void create(JobNo jobNo) {
        jobNoMapper.insertSelective(jobNo);
    }

    @Override
    public void update(JobNo jobNo) {
      jobNoMapper.updateByPrimaryKeySelective(jobNo);
    }

    @Override
    public void delete(Long[] ids) {
        Weekend<JobNo> example = Weekend.of(JobNo.class);
        WeekendCriteria<JobNo,Object> criteria = example.weekendCriteria();
        criteria.andIn(JobNo::getId, Arrays.asList(ids));
        jobNoMapper.deleteByExample(example);
    }


    @Override
    public JobNo selectOneByAccount(String accountNo) {
        Weekend<JobNo> example = Weekend.of(JobNo.class);
        WeekendCriteria<JobNo,Object> criteria = example.weekendCriteria();
        criteria.orEqualTo(JobNo::getAcccount4a,accountNo);
        criteria.orEqualTo(JobNo::getAccountNo,accountNo);
        return jobNoMapper.selectOneByExample(example);
    }

    @Override
    public PageResultSet<JobNo> findByPager(JobNoQuery jobNoQuery) {
        if (!StringUtils.isEmpty(jobNoQuery.getOrderBy())){
            PageHelper.orderBy(jobNoQuery.getOrderBy());
        }
        PageHelper.offsetPage(jobNoQuery.getOffset(),jobNoQuery.getLimit());
        Weekend<JobNo> example = Weekend.of(JobNo.class);
        WeekendCriteria<JobNo,Object> criteria = example.weekendCriteria();
        if (!StringUtils.isEmpty(jobNoQuery.getEntityNo())){
            criteria.andLike(JobNo::getEntityNo,jobNoQuery.getEntityNo());
        }
        if (!StringUtils.isEmpty(jobNoQuery.getChineseNo())){
            criteria.andLike(JobNo::getChineseNo,jobNoQuery.getChineseNo());
        }
        if (!StringUtils.isEmpty(jobNoQuery.getAcccount4A())){
            criteria.andLike(JobNo::getAcccount4a,jobNoQuery.getAcccount4A());
        }

        List<JobNo> jobNos = jobNoMapper.selectByExample(example);
        long total = jobNoMapper.selectCountByExample(example);
        PageResultSet<JobNo> pageResultSet = new PageResultSet<>();
        pageResultSet.setRows(jobNos);
        pageResultSet.setTotal(total);
        return pageResultSet;
    }

    /**
     * 根据中文名称或者账号自动填充
     * @param query
     * @return
     */
    @Override
    public List<String> autoComplete(String query) {
        Weekend<JobNo> example = Weekend.of(JobNo.class);
        WeekendCriteria<JobNo,Object> criteria = example.weekendCriteria();
        String searcher = '%'+query+'%';
        criteria.orLike(JobNo::getChineseNo,searcher);
        criteria.orLike(JobNo::getAcccount4a,searcher);
        List<String> retList = new ArrayList<>();
         jobNoMapper.selectByExample(example).stream().map( o->{
               retList.add(o.getAcccount4a());
               retList.add(o.getNameBoss());
            return retList;
        }).collect(Collectors.toList());
        return retList;
    }


    @Cacheable(value = "jobNOListCache")
    @Override
    public String getAllJobNoINCache() {
        log.info("从数据库读取所有工号数据");
      List<JobNoDTO>  jobNoDTOS = jobNoMapper.selectAll().stream().map( o ->{
            JobNoDTO jobNoDTO = new JobNoDTO();
            try {
                BeanUtils.copyProperties(jobNoDTO,o);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            return jobNoDTO;
        }).collect(Collectors.toList());
      return JSON.toJSONString(jobNoDTOS);
    }

    @Override
    public List<JobNoDTO> ListAllDTO() {

      return   jobNoMapper.selectAll().stream().map( o ->{
          JobNoDTO jobNoDTO = new JobNoDTO();
          try {
              BeanUtils.copyProperties(jobNoDTO,o);
          } catch (IllegalAccessException e) {
              e.printStackTrace();
          } catch (InvocationTargetException e) {
              e.printStackTrace();
          }
          return jobNoDTO;
        }).collect(Collectors.toList());
    }




    /**
     * 将table中的字段嵌套关系转换为Tree关系，选择项过多时，方便UI使用树来多选关联
     * todo:目前Id采用×1000来进行，如果数据多是需要更改id生成规则
     * @return
     */
    @Override
    public List<TreeDto> list2Tree() {
        List<TreeDto> tds = new ArrayList<>();
        List<JobNoDTO> jobNoDTOList = ListAllDTO();
        //根据聚合，将city,country,entity 节点编号，用户构建父子节点编号
        Map<String,List<JobNoDTO>> collect = jobNoDTOList.stream().collect(Collectors.groupingBy(JobNoDTO::getCity));
        int nodeIdL1 = 1 ;
        for(Map.Entry<String,List<JobNoDTO>> entry : collect.entrySet()){
            //每一层节点深度占三维，否则会子节点会乱
              String tmpNodeL1 = ("00"+nodeIdL1);
            String id = "90"+ (tmpNodeL1.length()>3 ? tmpNodeL1.substring(tmpNodeL1.length()-3) : tmpNodeL1);
            //log.info("地市分组：{},子节点={}",entry.getKey(),JSON.toJSONString(entry.getValue()));
            tds.add(new TreeDto(Long.valueOf(id),Long.valueOf(0),entry.getKey(),true,entry.getValue()));
            Map<String,List<JobNoDTO>> collectL2 = entry.getValue().stream().collect(Collectors.groupingBy(JobNoDTO::getCountry));
            int nodeIdL2 = 1;
            for(Map.Entry<String,List<JobNoDTO>> entryL2 : collectL2.entrySet()){
                 String tmpNodeL2 = ("00"+nodeIdL2);
                String idL2 = id+(tmpNodeL2.length()>3 ? tmpNodeL2.substring(tmpNodeL2.length()-3) : tmpNodeL2);
                //log.info("县区分组：{},子节点={}",entryL2.getKey(),JSON.toJSONString(entryL2.getValue()));
                tds.add(new TreeDto(Long.valueOf(idL2),Long.valueOf(id),entryL2.getKey(),true,entryL2.getValue()));
                //添加叶子节点,后面不好关联对于记录，所以改用table id
                int nodeIdLeaf = 1;
                for (JobNoDTO jobNoDTO : entryL2.getValue()){
                    //String tmpNodeLeaf = "000"+nodeIdLeaf;
                    String tmpNodeLeaf = "0000"+jobNoDTO.getId();
                    String nodeIdLeafId = idL2+ (tmpNodeLeaf.length()>4 ? tmpNodeLeaf.substring(tmpNodeLeaf.length()-4) : tmpNodeLeaf);
                    tds.add(new TreeDto(Long.valueOf(nodeIdLeafId),Long.valueOf(idL2),jobNoDTO.getChineseNo(),false,jobNoDTO));
                   // log.info("工号节点：{}",jobNoDTO.getAcccount4a()+","+jobNoDTO.getAccountNo());
                    nodeIdLeaf ++;
                }
                nodeIdL2 ++ ;
            }

            nodeIdL1 ++;
            //递归
        }

        return tds.stream().map(o -> {
            o.setObj("");
            return o;
        }).collect(Collectors.toList());
    }


}
